﻿using BJoin.Application.AppException;
using BJoin.Application.Dto;
using BJoin.Application.WebApi.Controllers;
using BJoin.Application.WebApi.Extensions;
using BJoin.Common;
using BJoin.DemoProject.Dtos;
using BJoin.DemoProject.Service;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BJoin.DemoProject.RW.Webapi.Controllers.File
{
    [Produces("application/json")]
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [SwaggerTag("文件接口服务")]
    public class FileController : BaseController<FileController>
    {
        private readonly IFileService _service;
        public FileController(IFileService service, ILoggerFactory loggerFactory) : base(loggerFactory)
        {
            _service = service;
        }

        /// <summary>
        /// 限量带参(可空)筛选
        /// </summary>
        /// <param name="fisrtResult">从第几个</param>
        /// <param name="maxResult">到第几个</param>
        /// <param name="filterDto">对象的属性</param>
        /// <returns>IList对象集合</returns>
        /// <response code="200">返回IList对象集合</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="500">内部错误...</response>
        [HttpGet("filter")]
        [ProducesResponseType(typeof(IList<FileDto>), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> FilterAsync(int fisrtResult = 0, int maxResult = 10, [FromQuery] FileFilterDefaultOrderDto filterDto = null)
        {
            var result = await _service.FilterAsync(filterDto,filterDto?.OrderBy);
            return Ok(result);
        }

        /// <summary>
        /// 带参(可空)分页筛选
        /// </summary>
        /// <param name="pageIndex">分页索引</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="filterDto">对象的属性</param>
        /// <returns>ResPagingDto对象集合</returns>
        /// <response code="200">返回ResPagingDto对象集合</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="404">无记录</response>
        /// <response code="500">内部错误...</response>
        [HttpGet("filter/paging")]
        [ProducesResponseType(typeof(ResPagingDto<FileDto>), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> FilterPagingAsync(int pageIndex = 0, int pageSize = 20, [FromQuery] FileFilterDefaultOrderDto filterDto = null)
        {
            //IntValidation
            CheckPagingParm(pageIndex, pageSize);
            var result = await _service.PagingFilterAsync(filterDto, pageIndex, pageSize, filterDto?.OrderBy);
            return Ok(result);
        }

        /// <summary>
        /// 带参（可空）查询记录总数
        /// </summary>
        /// <param name="filterDto">对象的属性</param>
        /// <returns>总数</returns>
        /// <response code="200">返回数目</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="500">内部错误...</response>
        [HttpGet("count")]
        [ProducesResponseType(typeof(int), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> CountAsync([FromQuery]FileFilterDto filterDto=null)
        {
            var count = await _service.CountAsync(filterDto);
            return Ok(count);
        }
        /// <summary>
        /// 根据编码和名称查询记录总数(Expression)
        /// </summary>
        /// <param name="code">编码</param>
        /// <param name="name">名称</param>
        /// <returns>总数</returns>
        /// <response code="200">返回数目</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="500">内部错误...</response>
        [HttpGet("count-expression")]
        [ProducesResponseType(typeof(int), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> CountAsync(string name,string code="code1")
        {
            var count = await _service.HelloExpression(code,name);
            return Ok(count);
        }
        /// <summary>
        /// 根据ID获取(快速)
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>对象</returns>
        /// <response code="200">返回对象</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="404">无记录</response>
        /// <response code="500">内部错误...</response>
        [HttpGet("{id}")]
        [ProducesResponseType(typeof(FileDto), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 404)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> GetAsync(long id)
        {
            var result = await _service.GetFileWithFormatDesc(id);
            if (null == result)
                throw new HttpStatusCodeException(StatusCodes.Status404NotFound,
                    string.Format(EnumHelper.GetEnumDescription<MessageEnum>(MessageEnum.NotFound), nameof(id)));
            return Ok(result);
        }

        /// <summary>
        /// 单一新增
        /// </summary>
        /// <param name="addDto">Add对象</param>
        /// <returns>对象</returns>
        /// <response code="200">返回新创建对象Id</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="500">内部错误...</response>
        [HttpPost]
        [ProducesResponseType(typeof(long), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        //[SwaggerOperation(
        //    Summary = "Creates a new product",
        //    Description = "Requires admin privileges",
        //    OperationId = "CreateProduct",
        //    Tags = new[] { "Purchase", "Products" }
        //)]
        public async Task<IActionResult> AddAsync([FromBody]FileAddDto addDto)
        {
            var id = await _service.AddAsync(addDto);
            return Ok(id);
        }
        [HttpPost("BodyTypes/JsonStringBody")]
        public IActionResult JsonStringBody([FromBody] string content)
        {
            return Ok(content);
        }
        [HttpPost("BodyTypes/ReadStringDataManual")]
        public async Task<IActionResult> ReadStringDataManualAsync()
        {
            return Ok(await Request.GetRawBodyStringAsync());
        }
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="addDtos">AddDto对象集合</param>
        /// <returns>Id集合</returns>
        /// <response code="200">返回新创建对象Id集合</response>
        /// <response code="400">参数不正确</response>
        /// <response code="500">内部错误</response>
        [HttpPost("many")]
        [DisableRequestSizeLimit]
        [ProducesResponseType(typeof(bool), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> AddManyAsync([FromBody]IList<FileAddDto> addDtos)
        {
            var result = await _service.AddManyAsync(addDtos);
            return Ok(result);
        }
        /// <summary>
        /// 更新对象(全部属性更新，支持Null)
        /// </summary>
        /// <param name="id">ID</param>
        /// <param name="updateDto">UpdateDto对象的属性</param>
        /// <returns>true或false</returns>
        /// <response code="200">返回true或false</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="404">无记录</response>
        /// <response code="500">内部错误...</response>
        [HttpPut("{id}")]
        [ProducesResponseType(typeof(bool), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 404)]
        [ProducesResponseType(typeof(string), 500)]
        [Obsolete("obsolete example")]
        public async Task<IActionResult> PutAsync(long id, [FromBody] FileUpdateDto updateDto)
        {
            var result = await _service.UpdateAsync(id,updateDto);
            return Ok(result);
        }
        /// <summary>
        /// 更新对象（更新单一或多个属性）
        /// </summary>
        /// <param name="id">ID</param>
        /// <param name="updateDto">UpdateDto对象的属性</param>
        /// <returns>true或false</returns>
        /// <response code="200">返回true或false</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="404">无记录</response>
        /// <response code="500">内部错误...</response>
        [HttpPatch("{id}")]
        [ProducesResponseType(typeof(bool), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 404)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> PatchAsync(long id, [FromBody]FileUpdateDto updateDto)
        {
            var result = await _service.UpdateSetAsync(id, updateDto);
            return Ok(result);
        }

        /// <summary>
        /// 根据单一ID删除
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>true/false</returns>
        /// <response code="200">返回true或false(无记录)</response>
        /// <response code="400">参数不正确...</response>
        /// <response code="500">内部错误...</response>
        [HttpDelete("{id}")]
        [ProducesResponseType(typeof(bool), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> DeleteAsync(long id)
        {
            CheckId(id);
            var result = await _service.DeleteAsync(id);
            return Ok(result);
        }

        /// <summary>
        /// 根据多个ID删除
        /// </summary>
        /// <param name="ids">多个ID,逗号分隔</param>
        /// <returns>true/false</returns>
        /// <response code="200">返回true或false(无记录)</response>
        /// <response code="400">参数不正确</response>
        /// <response code="500">内部错误</response>
        [HttpDelete("ids/{ids}")]
        [ProducesResponseType(typeof(bool), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(typeof(string), 500)]
        public async Task<IActionResult> DeleteManyAsync(string ids)
        {
            CheckIds(ids);
            var result = await _service.DeleteManyAsync(ids);
            return Ok(result);
        }
    }
}